<!-- 角色 -->
<template>
  <div class="container">
    <div class="app-container">
      <el-card>
        <el-button style="margin-bottom: 20px" type="primary" size="small" @click="dialogFormVisible = true">添加角色</el-button>
        <el-table :data="tableData" border>
          <el-table-column label="序号" prop="name" width="50" align="center">
            <!-- 作用域插槽 v-slot="" -> 等价于 #default="" -->
            <template #default="{$index}">
              <!-- 序号连续 -->
              {{ $index + 1 + (pageParams.page - 1) * pageParams.pagesize }}
            </template>
          </el-table-column>
          <el-table-column label="角色" width="200" align="center">
            <!-- 自定义表格 -->
            <template #default="{row}">
              <!-- 1.2 双向绑定定义的备用数据, 到时候发修改请求的时候也是提交备用数据, 覆盖原始数据 -->
              <el-input v-if="row.isEdit" v-model="row.editRow.name" />
              <div v-else>{{ row.name }}</div>
            </template>
          </el-table-column>
          <el-table-column label="启用" prop="state" width="200" align="center">
            <!-- 表格是使用插槽才能转换数据 -->
            <template #default="{row}">
              <el-switch
                v-if="row.isEdit"
                v-model="row.editRow.state"
                :active-value="1"
                :inactive-value="0"
              />
              <div v-else> {{ row.state ? '已启用' : '未启用' }}</div>
            </template>
          </el-table-column>
          <el-table-column label="描述" width="658" align="center">
            <template #default="{row}">
              <el-input v-if="row.isEdit" v-model="row.editRow.description" type="textarea" />
              <div v-else>{{ row.description }}</div>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center">
            <template #default="{row}">
              <div v-if="!row.isEdit">
                <el-button type="text" size="small" @click="onShowPermission(row.id)">分配权限</el-button>
                <el-button type="text" size="small" @click="row.isEdit = true">编辑</el-button>
                <el-button type="text" size="small" @click="popoverVisible = true">删除</el-button>
              </div>
              <div v-else>
                <el-button type="primary" size="small" @click="onConfirm(row)">确定</el-button>
                <el-button size="small" @click="oncancel(row)">取消</el-button>
              </div>
            </template>
          </el-table-column>
          <!-- <el-popover v-model="popoverVisible" placement="top" width="200">
            <p>这是一段内容这是一段内容确定删除吗？</p>
          </el-popover> -->
        </el-table>

        <el-row type="flex" justify="center" style="height: 60px;" align="middle">
          <!-- prev左箭头 pager页数 next右箭头
           page-size 每页显示多少条数据
           total总条数
           current-page当前页码
           @current-change页码改变
          -->
          <el-pagination
            layout="prev, pager, next"
            :page-size="pageParams.pagesize"
            :total="pageParams.total"
            :current-page="pageParams.page"
            @current-change="currentChang"
          />
        </el-row>
      </el-card>

      <!-- 对话框 -->
      <el-dialog title="添加角色" :visible.sync="dialogFormVisible" width="30%">
        <el-form ref="form" :model="form" :rules="rules">

          <el-form-item label="角色名称" prop="name">
            <el-input v-model="form.name" />
          </el-form-item>
          <el-form-item label="角色状态" prop="state">
            <!-- 开关 active-value选中的值 inactive-value未选中的值 -->
            <el-switch
              v-model="form.state"
              :active-value="1"
              :inactive-value="0"
            />
          </el-form-item>
          <el-form-item label="角色描述" prop="description">
            <el-input v-model="form.description" type="textarea" />
          </el-form-item>

          <el-row type="flex" justify="center">
            <el-button type="primary" size="small" @click="onSubmit">确 定</el-button>
            <el-button size="small" @click="dialogFormVisible = false">取消</el-button>
          </el-row>
        </el-form>
      </el-dialog>

      <!-- 分配权限对话框 -->
      <el-dialog title="分配权限" :visible.sync="permissionShowDialog">
        <!--
            default-expand-all 默认展开所有节点
            expand-on-click-node 点击节点时是否自动展开节点
            show-checkbox 显示复选框
            check-strictly 遵循父子不互相关联的做法, 默认为false
            default-checked-keys 默认选中的节点的key  需配合node-key使用
            node-key="id" 指定节点id作为唯一标识
            getCheckedKeys 返回被选中的子节点的keys集合,组成一个数组, tree内部方法,需要用ref获取
        -->
        <el-tree
          ref="treeRef"
          :default-expand-all="true"
          :expand-on-click-node="false"
          show-checkbox
          :check-strictly="true"
          node-key="id"
          :default-checked-keys="defaultCheckedKeys"
          :data="treePermissionList"
          :props="{label:'name'}"
        />
        <el-row type="flex" justify="center" style="margin-top: 20px;">
          <el-button type="primary" size="mini" @click="onSaveRole">确定</el-button>
          <el-button size="mini">取消</el-button>
        </el-row>
      </el-dialog>
    </div>
  </div>
</template>
<script>
import { getPermissionListAPI } from '@/api/permission'
import { addRoleAPI, assignPermAPI, editRoleAPI, getRoleAPI, getRoleDetailAPI } from '@/api/role'
import { arrayToTree } from '@/utils'

export default {
  name: 'Role',
  data() {
    return {
      defaultCheckedKeys: [], // tree默认选中的节点
      permissionShowDialog: false, // 分配权限对话框
      treePermissionList: [], // 权限树
      dialogFormVisible: false, // 添加弹窗显示隐藏
      popoverVisible: false, // 控制删除弹窗显示隐藏
      tableData: [], // 表格数据
      pageParams: {
        page: 1, // 当前页码
        pagesize: 5, // 每页显示多少条数据
        total: 0 // 总条数
      },
      form: {
        name: '',
        description: '',
        state: 0
      },
      switchValue: false, // 开关状态
      rules: {
        name: [
          { required: true, message: '请输入角色名称', trigger: 'blur' }
        ],
        description: [
          { required: true, message: '请输入角色描述', trigger: 'blur' },
          { min: 3, max: 50, message: '长度在 3 到 50 个字符', trigger: 'blur' }
        ]
      }
    }
  },
  watch: {
    // 对话框隐藏: 重置表单与重置校验
    dialogFormVisible(newVal) {
      if (!newVal) {
        this.$refs.form.resetFields()
      }
    }
  },
  created() {
    this.getData()
  },
  methods: {

    // 获取表格数据
    async getData() {
      const { rows, total } = await getRoleAPI(this.pageParams)
      this.tableData = rows
      this.pageParams.total = total
      this.tableData.forEach(item => {
        // item.isEdit = false
        // 数组已 经过创建,挂载阶段, 如果再手动修改数组, 视图并不会更新, 所以需要使用this.$set()方法更新视图
        this.$set(item, 'isEdit', false) // this.$set(对象, '变量', 值) - 给每一项数据添加一个isEdit属性
        // 1.1 防止修改时,修改了原始数据,造成污染, 定义一个新的对象, 用来存储修改后的数据
        this.$set(item, 'editRow', {
          name: item.name,
          state: item.state,
          description: item.description
        })
      })
    },
    // 切换页码
    currentChang(page) {
      this.pageParams.page = page
      this.getData() // 切换页码重新获取此页码的相应的数据
    },
    // 添加角色
    async onSubmit() {
      await this.$refs.form.validate()
      await addRoleAPI(this.form) // 添加角色接口
      this.$message.success('添加成功')
      this.dialogFormVisible = false // 关闭弹窗
      this.getData()
    },
    // 1.3 点击取消
    oncancel(row) {
      row.isEdit = false // 1.4 取消编辑状态
      // 1.5重置备用数据-再次打开编辑时, 回显原始数据
      row.editRow = {
        name: row.name,
        description: row.description,
        state: row.state
      }
    },
    // 点击确定修改
    async onConfirm(row) {
      if (!row.editRow.name) return this.$message.warning('请输入角色名称')
      if (!row.editRow.description) return this.$message.warning('请输入角色描述')
      await editRoleAPI({ id: row.id, ...row.editRow }) // 修改角色接口
      this.$message.success('修改成功')
      this.getData()
    },
    // 点击分配权限按钮
    async onShowPermission(id) {
      const res = await getPermissionListAPI() // 获取权限点
      this.treePermissionList = arrayToTree(res) // 转成树
      this.roleId = id // 动态存储角色id
      const { permIds } = await getRoleDetailAPI(id) // 获取角色的权限点
      this.defaultCheckedKeys = permIds // 赋值给默认选中的tree的keys集合
      this.permissionShowDialog = true
    },

    // 点击分配权限对话框的-确定分配权限
    async onSaveRole() {
      const res = this.$refs.treeRef.getCheckedKeys() //  getCheckedKeys 返回被选中的子节点的keys集合,组成一个数组,
      await assignPermAPI({ id: this.roleId, permIds: res }) // 分配权限-角色接口
      this.$message.success('分配权限成功')
      this.permissionShowDialog = false
    }
  }
}
</script>

